package com.gxc.service.common.components.log.config;

import com.gxc.service.common.components.log.aspect.LogAspect;
import com.gxc.service.common.components.log.feign.GlobalFeignInterceptor;
import com.gxc.service.common.components.log.filter.LogCollectFilter;
import com.gxc.service.common.components.log.mq.LogMqSender;
import com.gxc.service.common.config.feign.FeignHystrixConcurrencyStrategy;
import com.gxc.service.common.model.constant.RabbitMqConstant;
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
import feign.RequestInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.context.annotation.Bean;

import javax.servlet.Filter;

/**
 * 日志收集器配置类.
 *
 * @author GongXincheng
 * @since 2019-11-08 21:20
 */
@Slf4j
public class LogCollectConfiguration {

    /**
     * 日志过滤器
     */
    @Bean
    public Filter logCollectFilter() {
        return new LogCollectFilter();
    }

    /**
     * 日志切面
     */
    @Bean
    public LogAspect logAspect() {
        return new LogAspect();
    }

    /**
     * mq发送者.
     */
    @Bean
    public LogMqSender logMqSender() {
        return new LogMqSender();
    }

    /**
     * feign调用设置请求头.
     */
    @Bean
    public RequestInterceptor globalFeignInterceptor() {
        return new GlobalFeignInterceptor();
    }

    /**
     * feign 启用 Hystrix 时，因为默认的线程隔离策略，导致 LocalThread 失效，例如  RequestContextHolder.getRequestAttributes() 返回 null。
     * 使用该 bean 自定义隔离策略，防止失效。
     */
    @Bean
    public HystrixConcurrencyStrategy feignHystrixConcurrencyStrategy() {
        return new FeignHystrixConcurrencyStrategy();
    }

    /////////////////////  MQ配置 /////////////////////

    @Bean
    public Queue requestInfoLogQueue() {
        return new Queue(RabbitMqConstant.QUEUE_NAME_LOG);
    }

    @Bean
    public TopicExchange logExchange() {
        return new TopicExchange(RabbitMqConstant.EXCHANGE_NAME_LOG, true, false);
    }

    @Bean
    public Binding logBinding() {
        return BindingBuilder.bind(requestInfoLogQueue()).to(logExchange()).with(RabbitMqConstant.QUEUE_NAME_LOG);
    }

    @Bean
    public Jackson2JsonMessageConverter jackson2JsonMessageConverter() {
        return new Jackson2JsonMessageConverter();
    }

    ///////////////////////////////////////////////////
}
